package com.chinaway.mobile.service;

import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.chinaway.mobile.balance.MobileBalance;
import com.chinaway.mobile.balance.impl.MobileBalanceSdImpl;
import com.chinaway.mobile.dao.SimDao;
import com.chinaway.mobile.dao.SimbalanceworkDao;
import com.chinaway.mobile.model.Account;
import com.chinaway.mobile.model.Sim;
import com.chinaway.mobile.model.Simbalancework;
import com.chinaway.router.HandlerException;

public class SimbalanceworkService implements Runnable{
	
	private final Logger log = LoggerFactory.getLogger(getClass());
	
	
	private SimDao simDao;
	private SimbalanceworkDao simbalanceworkDao;
	
	
	//已经执行过的 simmap
	private static Map<String,Simbalancework> simmap = new HashMap<String,Simbalancework>();
	//任务map
	private static Map<Long,WorkDes> workmap = new HashMap<Long,WorkDes>();
	private static Queue<Long> workids = new LinkedList<Long>();
	//执行任务
	private static boolean running = false;//正在运行
	private static boolean start = false;//启动
	
	private static Long sleeptime = 60000L;
	public void execution(Long worid){
		start = true;
		WorkDes wd = workmap.get(worid);
		Date date  = new Date();
		if(wd==null){
			 wd = new WorkDes();
			 workmap.put(worid, wd);
		}else{
			if(Math.abs(wd.getDate().getTime()-date.getTime())<86400000){
				return;
			}else{
				wd.setDate(date);
				wd.setMode(0);
			}
		}
		workids.add(worid);
	}
	
	
	public void  stop(Long worid){
		WorkDes wd = workmap.get(worid);
		if(wd!=null){
			Date date  = new Date();
			if(Math.abs(wd.getDate().getTime()-date.getTime())<86400000){
				wd.setMode(1);
			}else{
				workmap.remove(worid);
				throw  new HandlerException(703,"任务已经过期");
			}
		}else{
			execution(worid);
		}
		
	}
	
	@Override
	public void run() {
		while(start){
			 try {
			 	if(!running){
			 		Long workid =  workids.poll();
					if(workid!=null){
						runwork(workid);
					}else{
						start = false;
					}
			 	}
			 	Thread.sleep(sleeptime);
				} catch (Exception e) {
				}
		}
	}
	
	
	public void runwork(Long workid){
		if(running)return;
		running = true;
		Date date = new Date();
		List<Simbalancework> sbwList = simbalanceworkDao.findby(workid);
		sleeptime = sbwList.size()*300L;
		for(Simbalancework sbw:sbwList){
			WorkDes wd = workmap.get(workid);
			if(wd.getMode()>0)break;
			if(ishave(sbw.getSim(),date))continue;
			Account account  = new Account(sbw.getSim(),sbw.getPassword(),sbw.getProvcode());
			try {
				account = getAccount(account);
				if(account==null)continue;
				Sim sim = new Sim(account);
				simDao.update(sim);
				
				sbw.setResult(account.getBalance());
				sbw.setIsok(true);
				sbw.setUpdatetime(new Date());
				simbalanceworkDao.update(sbw);
				simmap.put(sbw.getSim(), sbw);
				wd.setMode(3);
			} catch (Exception e) {
				log.debug(account.toString()+"查询异常",e);
			}
		}
		running = false;
	}
	
	private boolean ishave(String mobile,Date time){
		Simbalancework mapsbw =simmap.get(mobile);
		if(mapsbw!=null &&  Math.abs(mapsbw.getUpdatetime().getTime()-time.getTime())<86400000){
			return true;
		}
		return false;
	}
	
	private  Account getAccount(Account account){
		if("sd".equals(account.getCity())){
			MobileBalance m = new MobileBalanceSdImpl();
			account = m.account(account.getMobile(), account.getPassword(), null, null) ;
		}else{
			return null;
		}
		return account;
	}
	
	
	public class WorkDes{
		private Date date;
		private int mode; //0 执行,1 暂停,,执行完成
		
		public WorkDes(){
			this.date = new Date();
		}
		public WorkDes(Date date){
			this.date = date;
		}
		
		public WorkDes(Date date,int mode){
			this.date = date;
			this.mode = mode;
		}
		public Date getDate() {
			return date;
		}
		public void setDate(Date date) {
			this.date = date;
		}
		public int getMode() {
			return mode;
		}
		public void setMode(int mode) {
			this.mode = mode;
		}
		 
	}
	public void setSimDao(SimDao simDao) {
		this.simDao = simDao;
	}
	
	public void setSimbalanceworkDao(SimbalanceworkDao simbalanceworkDao) {
		this.simbalanceworkDao = simbalanceworkDao;
	}
	
	protected ExecutorService executor;
	public void start(){
		log.info("启动手机余额手动查询模块");
		start = true;
		executor = Executors.newSingleThreadExecutor(new ThreadFactory() {
			public Thread newThread(Runnable runable) {
				return new Thread(runable, getClass().getSimpleName());
			}
		});
		executor.execute(this);
	}
}
